package com.sihai.ehr.service.impl;

import com.sihai.core.*;
import com.sihai.ehr.model.biz.Duty;
import com.sihai.ehr.service.DutyService;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.List;

/**
 * User: xiao
 * Date: 12-6-6
 */
@Service("dutyService")
public class DutyServiceImpl implements DutyService{
    @Resource
    private DataAccessor dataAccessor;

    @Override
    public Duty get(Long id) {
        if(id == null){
            return null;
        }

        return dataAccessor.get(Duty.class, id);
    }

    @Override
    public List<Duty> searchWithPath(Long organizationId, Limit limit, Sorter sorter) {
        if(organizationId == null){
            return dataAccessor.findByHql(Duty.class, "select new Duty(d.id, d.dutyName, d.organization) from Duty d where d.cancel <> 1", null, limit, sorter);
        }
        return dataAccessor.findByHql(Duty.class, "select new Duty(d.id, d.dutyName, d.organization) from Duty d where d.cancel <> 1 and d.organization.id = ?", new Object[]{organizationId}, limit, sorter);
    }

    @Override
    public List<Duty> search(Long organizationId, Limit limit, Sorter sorter) {
        if(organizationId == null){
            return dataAccessor.findByHql(Duty.class, "select new Duty(id, dutyName) from Duty where cancel <> 1", null, limit, sorter);
        }
        return dataAccessor.findByHql(Duty.class, "select new Duty(id, dutyName) from Duty where cancel <> 1 and organization.id = ?", new Object[]{organizationId}, limit, sorter);
    }

    @Override
    public List<Duty> searchDuty(Long organizationId, Limit limit, Sorter sorter) {
        if(organizationId == null){
                   return dataAccessor.findByHql(Duty.class, "select new Duty(id, dutyName) from Duty where cancel <> 1", null, limit, sorter);
               }
        return dataAccessor.findByHql(Duty.class, "select new Duty(id, dutyName) from Duty where cancel <> 1 and organization.id = ?", new Object[]{organizationId}, limit, sorter);
    }

    @Override
    public LimitedList<Duty> search(final Duty duty, Limit limit, Sorter sorter) {
        if(duty == null){
            return dataAccessor.findByClass(Duty.class, limit, sorter);
        }
        return dataAccessor.findByQuery(Duty.class, new QueryCreator() {
            @Override
            public Query createQuery(Session session) {
                DynamicQuery dynamicQuery = new DynamicQuery("from Duty d where d.cancel <> 1 ");
                if(duty.getOrganization() != null){
                    dynamicQuery.appendIfNotNull("and d.organization.id = :organization", "organization", duty.getOrganization().getId());
                }
                dynamicQuery.appendIfNotNull("and d.dutyName like :dutyName", "dutyName", duty.getDutyName());
                dynamicQuery.appendIfNotNull("and d.dutyContent like :dutyContent", "dutyContent", duty.getDutyContent());

                return dynamicQuery.build(session);
            }
        }, limit, sorter);
    }

    @Override
    public void save(Duty duty) {
        if(duty != null){
            dataAccessor.save(duty);
        }
    }

    @Override
    public void remove(final String dutyIds) {
        if(dutyIds == null || dutyIds.isEmpty()){
            return;
        }

        dataAccessor.batchUpdate(new QueryCreator() {
            @Override
            public Query createQuery(Session session) {
                //Query query = session.createQuery("update Duty d set d.cancel = 1 where d.id in (:dutyIds)");
                //QueryHelper.setParameter(query, dutyIds);
                //query.setParameterList("dutyIds", dutyIds);
                //return query;

                return session.createQuery(String.format("update Duty d set d.cancel = 1 where d.id in (%s)", dutyIds));
            }
        });
    }

    @Override
    public LimitedList<Duty> findForRole(Long organizationId, Limit limit, Sorter sorter)throws Exception{
        Assert.notNull(organizationId, "organization is required");
        return dataAccessor.findByHql(Duty.class, "from Duty d where d.organization.topOrganization.id=? and d.id not in(select r.duty.id from Role r)", new Object[]{organizationId}, limit, sorter);
    }
}
